package com.dirox.jira.notes.action;

import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.issue.IssueManager;
import com.atlassian.jira.issue.MutableIssue;
import com.atlassian.jira.rest.api.util.ErrorCollection;
import com.atlassian.jira.security.PermissionManager;
import com.atlassian.jira.security.Permissions;
import com.atlassian.jira.security.xsrf.RequiresXsrfCheck;
import com.atlassian.jira.web.action.JiraWebActionSupport;
import com.atlassian.plugins.rest.common.json.DefaultJaxbJsonMarshaller;
import com.atlassian.plugins.rest.common.json.JaxbJsonMarshaller;
import com.dirox.jira.notes.entities.Note;
import com.dirox.jira.notes.service.NoteService;
import org.apache.commons.lang.StringUtils;
import webwork.action.ActionContext;
import java.util.Hashtable;


public class UpdateMemo extends JiraWebActionSupport {
	private static final long serialVersionUID = 1L;
	private NoteService noteService;
	private IssueManager issueManager;
	private PermissionManager permissionManager;
	private ErrorCollection errors;
	private Hashtable<String, Object> responseJson;
	private String noteId;
	private String issueKey;

	/**
	 * This method is execute action to u note
	 *
	 * @return JSON content
	 */
	@RequiresXsrfCheck
	protected String doExecute() throws Exception {
		// validate the input parameters
		if (!validateInput()) {
			return ERROR;
		}

		ActionContext.getResponse()
		             .setContentType("application/json");

		Note note = noteService.getNote(Integer.parseInt(noteId));

		// update tagged issues
		Issue[] listIssues;

		if (!StringUtils.isBlank(issueKey)) {
			listIssues = new Issue[] { issueManager.getIssueObject(issueKey) };
		} else {
			listIssues = new Issue[] {  };
		}

		noteService.associateIssues(note, listIssues);

		this.responseJson = new Hashtable<String, Object>();
		this.responseJson.put("response",
		                      getText("notes.code.success"));
		this.responseJson.put("success", true);

		return "json";
	}

	/**
	 * Validate the input parameters
	 *
	 * @return true if validating input success, else return false
	 */
	private boolean validateInput() {
		// check if note id is not an integer number
		if (StringUtils.isBlank(noteId) || !isInteger(noteId)) {
			this.errors = ErrorCollection.of(
				getText("notes.error.note.id.must.be.integer"));

			return false;
		}

		// check if note does not exist
		if (noteService.getNote(Integer.parseInt(noteId)) == null) {
			this.errors = ErrorCollection.of(
				getText("notes.error.not.exist.note"));

			return false;
		}

		// validation issue
		if (!StringUtils.isBlank(issueKey) && !issueKey.equals("-1")) {
			MutableIssue issue = issueManager.getIssueObject(issueKey);

			// check if issue does not exist
			if (issue == null) {
				this.errors = ErrorCollection.of(
					getText("notes.error.not.exist.issue"));

				return false;
			}

			// check if no permission on the issue
			if (!permissionManager.hasPermission(
					Permissions.BROWSE,
					issue,
					getLoggedInUser())) {
				this.errors = ErrorCollection.of(
					getText("notes.error.no.browse.permission.issue"));

				return false;
			}
		}

		return true;
	}

	private boolean isInteger(String s) {
		try {
			Integer.parseInt(s);
		} catch (NumberFormatException e) {
			return false;
		}

		return true;
	}

	public String getResponseJson() {
		final JaxbJsonMarshaller marshaller = new DefaultJaxbJsonMarshaller();

		return marshaller.marshal(this.responseJson);
	}

	public String getErrorJson() {
		final JaxbJsonMarshaller marshaller = new DefaultJaxbJsonMarshaller();
		this.responseJson = new Hashtable<String, Object>();
		this.responseJson.put("response", errors);
		this.responseJson.put("success", false);

		return marshaller.marshal(this.responseJson);
	}

	public void setId(String id) {
		this.noteId = id;
	}

	public void setIssueKey(String issueKey) {
		this.issueKey = issueKey;
	}

	public void setNoteService(NoteService noteService) {
		this.noteService = noteService;
	}

	public void setIssueManager(IssueManager issueManager) {
		this.issueManager = issueManager;
	}

	public void setPermissionManager(PermissionManager permissionManager) {
		this.permissionManager = permissionManager;
	}
}
